﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Globalization
Imports System.Linq
Imports Newtonsoft.Json
Imports roncliProductions.LibWowArmory.Extensions
Imports roncliProductions.LibWowArmory.Internationalization

Namespace roncliProductions.LibWowArmory.Realms

    ''' <summary>
    ''' A class that retrieves realm status information from the Blizzard WoW API.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class RealmStatus
        Inherits WowArmoryData

        Private rRealms As New Schema.realms

#Region "WowArmoryData Overrides"

#Region "Public Properties"

        ''' <summary>
        ''' The LastModified property is not implemented for realm status.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>The realm status API resource does not honor the Last-Modified HTTP header.  See http://us.battle.net/wow/en/forum/topic/2743700663</remarks>
        Public Overrides Property LastModified As Date
            Get
                Return Date.MinValue
            End Get
            Set(value As Date)
                If value <> Date.MinValue Then
                    Dim ex As New NotImplementedException("The realm status API resource does not honor the Last-Modified HTTP header.")
                    ex.Data.Add("Source", "http://us.battle.net/wow/en/forum/topic/2743700663")
                    Throw ex
                End If
            End Set
        End Property

        ''' <summary>
        ''' The length of time the data should be cached for, defaulting to 15 minutes for realm status information.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides Property CacheLength As New TimeSpan(0, 15, 0)

#End Region

#Region "Protected Properties"

        Protected Overrides ReadOnly Property URI As Uri
            Get
                QueryString.Clear()
                If Options.Realms.Count > 0 Then
                    QueryString.Add("realms", RealmList)
                End If
                Return New Uri("/api/wow/realm/status", UriKind.Relative)
            End Get
        End Property

        Protected Overrides ReadOnly Property CacheKey As String
            Get
                Return String.Format(CultureInfo.InvariantCulture, "LibWowArmory.RealmStatus.{0}", RealmList)
            End Get
        End Property

#End Region

#End Region

#Region "Properties"

#Region "Public"

        ''' <summary>
        ''' The options for looking up realm status information.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Options As New RealmStatusOptions

        Private colRealms As Collection(Of Realm)
        ''' <summary>
        ''' A list of realm status information as returned from the Blizzard WoW API.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Realms As Collection(Of Realm)
            Get
                Return colRealms
            End Get
        End Property

#End Region

#Region "Private"

        Private ReadOnly Property RealmList As String
            Get
                Return String.Join(",", Options.Realms)
            End Get
        End Property

#End Region

#End Region

#Region "Methods"

#Region "Constructors"

        ''' <summary>
        ''' A default constructor to retrieve realm status information from the Blizzard WoW API.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
        End Sub

        ''' <summary>
        ''' A constructor to retrieve realm status information for a single realm.
        ''' </summary>
        ''' <param name="strRealm"></param>
        ''' <remarks></remarks>
        Public Sub New(strRealm As String)
            Options.Realms.Add(strRealm)
            Load()
        End Sub

        ''' <summary>
        ''' A constructor to retrieve realm status information for multiple realms.
        ''' </summary>
        ''' <param name="strRealm"></param>
        ''' <remarks></remarks>
        Public Sub New(strRealm As IEnumerable(Of String))
            Options.Realms.AddRange(strRealm)
            Load()
        End Sub

        ''' <summary>
        ''' A constructor to retrieve realm status information for a specific region and language from the Blizzard WoW API.
        ''' </summary>
        ''' <param name="rRegion"></param>
        ''' <param name="lLanguage"></param>
        ''' <remarks></remarks>
        Public Sub New(rRegion As Region, lLanguage As Language)
            Region = rRegion
            Language = lLanguage
        End Sub

        ''' <summary>
        ''' A constructor to retrieve realm status information for a single realm for a specific region and language.
        ''' </summary>
        ''' <param name="rRegion"></param>
        ''' <param name="lLanguage"></param>
        ''' <param name="strRealm"></param>
        ''' <remarks></remarks>
        Public Sub New(rRegion As Region, lLanguage As Language, strRealm As String)
            Me.New(rRegion, lLanguage)
            Options.Realms.Add(strRealm)
            Load()
        End Sub

        ''' <summary>
        ''' A constructor to retrieve realm status information for multiple realms for a specific region and language.
        ''' </summary>
        ''' <param name="rRegion"></param>
        ''' <param name="lLanguage"></param>
        ''' <param name="strRealm"></param>
        ''' <remarks></remarks>
        Public Sub New(rRegion As Region, lLanguage As Language, strRealm As IEnumerable(Of String))
            Me.New(rRegion, lLanguage)
            Options.Realms.AddRange(strRealm)
            Load()
        End Sub

#End Region

        ''' <summary>
        ''' Loads the realm status.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            MyBase.Retrieve()
            rRealms = CType(JsonConvert.DeserializeObject(Data, GetType(Schema.realms)), Schema.realms)
            colRealms = (From r In rRealms.realms
                         Select New Realm(r.type.GetRealmType(), r.queue, r.status, r.population, r.name, r.slug)
                         ).ToCollection()
        End Sub

#End Region

    End Class

End Namespace
